#include "W5500_Abs.h"

#define W5500_REST_H	HAL_GPIO_WritePin(Reset_lan_GPIO_Port,Reset_lan_Pin,GPIO_PIN_SET)
#define W5500_REST_L	HAL_GPIO_WritePin(Reset_lan_GPIO_Port,Reset_lan_Pin,GPIO_PIN_RESET)

#define W5500_NSS_H	HAL_GPIO_WritePin(W5500_NSS_GPIO_Port,W5500_NSS_Pin,GPIO_PIN_SET)
#define W5500_NSS_L	HAL_GPIO_WritePin(W5500_NSS_GPIO_Port,W5500_NSS_Pin,GPIO_PIN_RESET)


uint8_t	 	Net_Status;
uint16_t	DstPort=9000;
uint8_t 	gDATABUF[DATA_BUF_SIZE];
uint8_t 	DstIP[4]={192,168,1,122};

network_state_t network_state;

wiz_NetInfo gWIZNETINFO = { .mac = {0x00, 0x08, 0xdc,0x11, 0x11, 0x11},
                            .ip = {192, 168, 1, 123},
                            .sn = {255,255,255,0},
                            .gw = {192, 168, 1, 1},
                            .dns = {8,8,8,8},
                            .dhcp = NETINFO_STATIC };

														
													

void SPI_WriteByte(uint8_t Tdata)
{
  HAL_SPI_Transmit(&hspi1,&Tdata,1,0xff);
}

uint8_t SPI_ReadByte(void)
{
	uint8_t data;
	HAL_SPI_Receive(&hspi1,&data,1,0xff);
	return data;
}

void SPI_CrisEnter(void)
{
    __set_PRIMASK(1);
}


void SPI_CrisExit(void)
{
    __set_PRIMASK(0);
}

void SPI_CS_Select(void)
{
    W5500_NSS_L;
}
void SPI_CS_Deselect(void)
{
    W5500_NSS_H;
}
void W5500_RESET(void)
{
    W5500_REST_L;
    HAL_Delay(50);
    W5500_REST_H;
    HAL_Delay(50);

}


void RegisterFunction(void)
{  

  reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit);    

#if   _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_
  reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);
#elif _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_
  reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);  
#else
   #if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SIP_) != _WIZCHIP_IO_MODE_SIP_
      #error "Unknown _WIZCHIP_IO_MODE_"
   #else
      reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect); 
   #endif
#endif
  reg_wizchip_spi_cbfunc(SPI_ReadByte, SPI_WriteByte);    
}


uint8_t ChipParametersConfiguration(void)
{
  uint8_t tmp;
  uint8_t memsize[2][8] = {{2,2,2,2,2,2,2,2},{2,2,2,2,2,2,2,2}};
	if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1)
		{
				return 0;
		}

	do
	{
		if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1)
		{
			return 0;
		}
	}
	while(tmp == PHY_LINK_OFF);
		
	return 1;
}

//初始化网络通讯参数,mac,ip等
void NetworkParameterConfiguration(void)  //Intialize the network information to be used in WIZCHIP

{

  uint8_t tmpstr[6];

  ctlnetwork(CN_SET_NETINFO, (void*)&gWIZNETINFO);

  ctlnetwork(CN_GET_NETINFO, (void*)&gWIZNETINFO);

  ctlwizchip(CW_GET_ID,(void*)tmpstr);
	

}

void W5500_ChipInit(void)
{
    RegisterFunction();
    W5500_RESET();
    ChipParametersConfiguration();
    NetworkParameterConfiguration();
}   

void do_tcpc(void)
{
	static uint16_t len=0;
	static uint8_t  state;
		
	state = getSn_SR(SOCK_TCPS);
	network_state.network_state = state;
	switch(state)														
	{
		case SOCK_INIT:															
				connect(SOCK_TCPS,DstIP,DstPort);
				break;
		case SOCK_ESTABLISHED:										
				if(getSn_IR(SOCK_TCPS) & Sn_IR_CON)   					
				{
					setSn_IR(SOCK_TCPS, Sn_IR_CON);								
				}
				len=getSn_RX_RSR(SOCK_TCPS);													
				if(len)
				{
					network_state.rec_len = len;				
				}											
		break;
		case SOCK_CLOSE_WAIT:												  
			disconnect(SOCK_TCPS);	
		break;
		case SOCK_CLOSED:														
				socket(SOCK_TCPS,Sn_MR_TCP,5000,Sn_MR_ND);		
		break;
		default:
			break;
	}
}

void do_tcpc_while(void)
{
	static uint16_t len=0;
	static uint8_t  state;
		
	while(1)
		{
			state = getSn_SR(SOCK_TCPS);
			network_state.network_state = state;
			switch(state)														
			{
				case SOCK_INIT:															
						connect(SOCK_TCPS,DstIP,DstPort);
						break;
				case SOCK_ESTABLISHED:										
						if(getSn_IR(SOCK_TCPS) & Sn_IR_CON)   					
						{
							setSn_IR(SOCK_TCPS, Sn_IR_CON);								
						}
						len=getSn_RX_RSR(SOCK_TCPS);													
						if(len)
						{
							network_state.rec_len = len;				
						}											
				break;
				case SOCK_CLOSE_WAIT:												  
					disconnect(SOCK_TCPS);	
				break;
				case SOCK_CLOSED:														
						socket(SOCK_TCPS,Sn_MR_TCP,5000,Sn_MR_ND);		
				break;
				default:
					break;
			}
		}
}
